#include <bits/stdc++.h>
#ifndef DEBUG
#define debug
#endif
using namespace std;
using i64 = int64_t;

int main() {
  cin.tie(0)->sync_with_stdio(0);
  string str;
  while (cin >> str) {
    int n = str.size();
    const int inf = INT_MAX / 2;
    vector<vector<int>> dp(n, vector<int>(n, inf));
    vector<vector<int>> opt(n, vector<int>(n));
    vector<int> pi(n, 0);
    for (int i = 0; i < n; i ++) dp[i][i] = 1;
    for (int l = n - 1; l >= 0; l --) {
      for (int r = l; r < n; r ++) {
        int len = r - l + 1;
        // 分两段
        for (int k = l; k < r; k ++) {
          if (dp[l][k] + dp[k + 1][r] < dp[l][r]) {
            dp[l][r] = dp[l][k] + dp[k + 1][r];
            opt[l][r] = k;
          }
        }
        // 自成一段
        // KMP（偏移 l 位)
        for (int i = l; i <= r; i ++) pi[i] = 0;
        for (int i = l + 1, len = 0; i <= r; i ++) {
          while (len && str[i] != str[l + len]) len = pi[l + len - 1];
          if (str[i] == str[l + len]) pi[i] = ++len;
        }
        if (pi[r] != 0 && len % (len - pi[r]) == 0) {
          int subLen = len - pi[r];
          int rep = len / subLen;
          int cnt = 2 + dp[l][l + subLen - 1];
          if (rep >= 100) cnt += 3;
          else if (rep >= 10) cnt += 2;
          else cnt += 1;
          if (cnt < dp[l][r]) {
            dp[l][r] = cnt;
            opt[l][r] = -subLen;
          }
        }
      }
    }
    auto output = [&](auto &self, int l, int r) {
      if (l == r) {
        cout << str[l];
        return;
      }
      if (opt[l][r] < 0) {
        int cnt = (r - l + 1) / -opt[l][r];
        cout << cnt << '(';
        self(self, l, l - opt[l][r] - 1);
        cout << ')';
        return;
      }
      self(self, l, opt[l][r]);
      self(self, opt[l][r] + 1, r);
    };
    output(output, 0, n - 1);
    cout << endl;
  }
}